use std::collections::HashMap;
use serde::{Deserialize, Serialize};
use crate::types::{GroupVersionKind, Object};

#[derive(Deserialize,Serialize,Default,Clone,Debug)]
pub struct Pod {
    pub kind:String,
    #[serde(rename="apiVersion")]
    pub api_version:String,
    pub metadata:ObjectMeta,
    #[serde(rename="spec")]
    pub pod_spec:PodSpec,
}

impl Object for Pod {
    fn group_version_kind(&self) -> GroupVersionKind {
        GroupVersionKind{
            group: "".to_string(),
            version: "v1".to_string(),
            kind: "pod".to_string()
        }
    }

    fn set_group_version_kind(&mut self, gvk: GroupVersionKind) {
        self.api_version = gvk.group_kind().string();
        self.kind = gvk.kind.clone();
    }
}


#[derive(Deserialize,Serialize,Default,Clone,Debug)]
pub struct ObjectMeta {
    pub name:String,
    #[serde(rename="generateName",default,skip_serializing_if="String::is_empty")]
    pub generate_name:String,
    pub namespace:String,
    #[serde(rename="selfLink",default,skip_serializing_if="String::is_empty")]
    pub self_link:String,
    #[serde(default,skip_serializing_if="String::is_empty")]
    pub uid:String,
    #[serde(rename="resourceVersion",default,skip_serializing_if="String::is_empty")]
    pub resource_version:String,
    #[serde(rename="generation",default,skip_serializing_if="String::is_empty")]
    pub generation:String,
    #[serde(rename="deletionGracePeriodSeconds",default,skip_serializing_if="Option::is_none")]
    pub deletion_grace_period_seconds:Option<i64>,
    #[serde(rename="labels",default,skip_serializing_if="HashMap::is_empty")]
    pub labels:HashMap<String,String>,
    #[serde(rename="annotations",default,skip_serializing_if="HashMap::is_empty")]
    pub annotations:HashMap<String,String>,
    #[serde(rename="clusterName",default,skip_serializing_if="String::is_empty")]
    pub cluster_name:String,
}

#[derive(Deserialize,Serialize,Default,Clone,Debug)]
pub struct PodSpec {
    #[serde(default,skip_serializing_if="Vec::is_empty")]
    pub volumes:Vec<Volume>,
    #[serde(rename="initContainers",default,skip_serializing_if="Vec::is_empty")]
    pub init_containers:Vec<Container>,
    #[serde(rename="containers",default,skip_serializing_if="Vec::is_empty")]
    pub containers:Vec<Container>,
    #[serde(rename="restartPolicy",default,skip_serializing_if="String::is_empty")]
    pub restart_policy:String,
    #[serde(rename="ephemeralContainers",default,skip_serializing_if="Vec::is_empty")]
    pub ephemeral_containers:Vec<EphemeralContainer>,
    #[serde(rename="terminationGracePeriodSeconds",default,skip_serializing_if="Option::is_none")]
    pub termination_grace_period_seconds:Option<i64>,
    #[serde(rename="activeDeadlineSeconds",default,skip_serializing_if="Option::is_none")]
    pub active_deadline_seconds:Option<i64>,
    #[serde(rename="dnsPolicy",default,skip_serializing_if="String::is_empty")]
    pub dns_policy:String,
    #[serde(rename="nodeSelector",default,skip_serializing_if="HashMap::is_empty")]
    pub node_selector:HashMap<String,String>,
    #[serde(rename="serviceAccountName",default,skip_serializing_if="String::is_empty")]
    pub service_account_name:String,
    #[serde(rename="serviceAccount",default,skip_serializing_if="String::is_empty")]
    pub deprecated_service_account:String,
    #[serde(rename="automountServiceAccountToken",default,skip_serializing_if="Option::is_none")]
    pub automount_service_account_token:Option<bool>,
    #[serde(rename="nodeName",default,skip_serializing_if="String::is_empty")]
    pub node_name:String,
    #[serde(rename="hostNetwork",default,skip_serializing_if="Option::is_none")]
    pub host_network:Option<bool>,
    #[serde(rename="hostPID",default,skip_serializing_if="Option::is_none")]
    pub host_pid:Option<bool>,
    #[serde(rename="hostIPC",default,skip_serializing_if="Option::is_none")]
    pub host_ipc:Option<bool>,
    #[serde(rename="shareProcessNamespace",default,skip_serializing_if="Option::is_none")]
    pub share_process_namespace:Option<bool>,
    #[serde(rename="securityContext",default,skip_serializing_if="Option::is_none")]
    pub security_context:Option<PodSecurityContext>,
    #[serde(rename="imagePullSecrets",default,skip_serializing_if="Vec::is_empty")]
    pub image_pull_secrets:Vec<String>,
    #[serde(rename="hostname",default,skip_serializing_if="String::is_empty")]
    pub hostname:String,
    #[serde(rename="subdomain",default,skip_serializing_if="String::is_empty")]
    pub subdomain:String,
}

#[derive(Deserialize,Serialize,Default,Clone,Debug)]
pub struct Volume {
    pub name:String,
    #[serde(rename="hostPath",default,skip_serializing_if="Option::is_none")]
    pub host_path:Option<HostPathVolumeSource>,
    #[serde(rename="emptyDir",default,skip_serializing_if="Option::is_none")]
    pub empty_dir:Option<EmptyDirVolumeSource>,
    #[serde(rename="persistentVolumeClaim",default,skip_serializing_if="Option::is_none")]
    pub persistent_volume_claim:Option<PersistentVolumeClaimVolumeSource>,
}

#[derive(Deserialize,Serialize,Default,Clone,Debug)]
pub struct HostPathVolumeSource {
    #[serde(default)]
    pub path:String,
    #[serde(rename="type")]
    pub typ:String,
}

#[derive(Deserialize,Serialize,Default,Clone,Debug)]
pub struct EmptyDirVolumeSource();

#[derive(Deserialize,Serialize,Default,Clone,Debug)]
pub struct PersistentVolumeClaimVolumeSource {
    #[serde(rename="claimName",default)]
    pub claim_name:String,
    #[serde(rename="readOnly")]
    pub read_only:bool,
}

#[derive(Deserialize,Serialize,Default,Clone,Debug)]
pub struct Container {
    pub name:String,
    pub image:String,
    #[serde(default,skip_serializing_if="Vec::is_empty")]
    pub command:Vec<String>,
    #[serde(default,skip_serializing_if="Vec::is_empty")]
    pub args:Vec<String>,
    #[serde(rename="workingDir",default,skip_serializing_if="String::is_empty")]
    pub working_dir:String,
    #[serde(default,skip_serializing_if="Vec::is_empty")]
    pub ports:Vec<ContainerPort>,
    #[serde(rename="envFrom",default,skip_serializing_if="Vec::is_empty")]
    pub env_from:Vec<EnvFromSource>,
    #[serde(rename="env",default,skip_serializing_if="Vec::is_empty")]
    pub env:Vec<EnvVar>,
    #[serde(default,skip_serializing_if="Option::is_none")]
    pub resources:Option<ResourceRequirements>,
    #[serde(rename="volumeMounts",default,skip_serializing_if="Vec::is_empty")]
    pub volume_mounts:Vec<VolumeMount>,
    #[serde(rename="volumeDevices",default,skip_serializing_if="Vec::is_empty")]
    pub volume_devices:Vec<VolumeMount>,
    #[serde(rename="livenessProbe",default,skip_serializing_if="Option::is_none")]
    pub liveness_probe:Option<Probe>,
    #[serde(rename="readinessProbe",default,skip_serializing_if="Option::is_none")]
    pub readiness_probe:Option<Probe>,
    #[serde(rename="startupProbe",default,skip_serializing_if="Option::is_none")]
    pub startup_probe:Option<Probe>,
    #[serde(rename="terminationMessagePath",default,skip_serializing_if="String::is_empty")]
    pub termination_message_path:String,
    #[serde(rename="terminationMessagePolicy",default,skip_serializing_if="String::is_empty")]
    pub termination_message_policy:String,
    #[serde(rename="imagePullPolicy",default,skip_serializing_if="String::is_empty")]
    pub image_pull_policy:String,
    #[serde(rename="securityContext",default,skip_serializing_if="Option::is_none")]
    pub security_context:Option<SecurityContext>,
    #[serde(rename="stdin",default,skip_serializing_if="Option::is_none")]
    pub stdin:Option<bool>,
    #[serde(rename="stdinOnce",default,skip_serializing_if="Option::is_none")]
    pub stdin_once:Option<bool>,
    #[serde(rename="tty",default,skip_serializing_if="Option::is_none")]
    pub tty:Option<bool>,
}


#[derive(Deserialize,Serialize,Default,Clone,Debug)]
pub struct ContainerPort {
    #[serde(rename="name",default,skip_serializing_if="String::is_empty")]
    pub name:String,
    #[serde(rename="hostPort",default,skip_serializing_if="Option::is_none")]
    pub host_port:Option<i32>,
    #[serde(rename="containerPort",default,skip_serializing_if="Option::is_none")]
    pub container_port:Option<i32>,
    #[serde(rename="protocol",default,skip_serializing_if="String::is_empty")]
    pub protocol:String,
    #[serde(rename="hostIP",default,skip_serializing_if="String::is_empty")]
    pub host_ip:String,
}

#[derive(Deserialize,Serialize,Default,Clone,Debug)]
pub struct EnvFromSource {
    #[serde(rename="prefix",default,skip_serializing_if="String::is_empty")]
    pub prefix:String,
    #[serde(rename="configMapRef",default,skip_serializing_if="Option::is_none")]
    pub config_map_ref:Option<ConfigMapEnvSource>,
    #[serde(rename="secretRef",default,skip_serializing_if="Option::is_none")]
    pub secret_ref:Option<SecretEnvSource>,
}

#[derive(Deserialize,Serialize,Default,Clone,Debug)]
pub struct ConfigMapEnvSource {
    #[serde(rename="name",default,skip_serializing_if="String::is_empty")]
    pub name:String,
    #[serde(rename="optional",default,skip_serializing_if="Option::is_none")]
    pub optional:Option<bool>,
}

#[derive(Deserialize,Serialize,Default,Clone,Debug)]
pub struct SecretEnvSource {
    #[serde(rename="name",default,skip_serializing_if="String::is_empty")]
    pub name:String,
    #[serde(rename="optional",default,skip_serializing_if="Option::is_none")]
    pub optional:Option<bool>,
}

#[derive(Deserialize,Serialize,Default,Clone,Debug)]
pub struct EnvVar {
    #[serde(rename="name")]
    pub name:String,
    #[serde(rename="value",default,skip_serializing_if="String::is_empty")]
    pub value:String,
    #[serde(rename="valueFrom",default,skip_serializing_if="Option::is_none")]
    pub value_from:Option<EnvVarSource>,
}

#[derive(Deserialize,Serialize,Default,Clone,Debug)]
pub struct EnvVarSource {
    #[serde(rename="fieldRef",default,skip_serializing_if="Option::is_none")]
    pub field_ref:Option<ObjectFieldSelector>,
    #[serde(rename="resourceFieldRef",default,skip_serializing_if="Option::is_none")]
    pub resource_field_ref:Option<ResourceFieldSelector>,
    #[serde(rename="configMapKeyRef",default,skip_serializing_if="Option::is_none")]
    pub config_map_key_ref:Option<ObjectFieldSelector>,
    #[serde(rename="secretKeyRef",default,skip_serializing_if="Option::is_none")]
    pub secret_key_ref:Option<ResourceFieldSelector>,
}


#[derive(Deserialize,Serialize,Default,Clone,Debug)]
pub struct ObjectFieldSelector {
    #[serde(rename="apiVersion",default,skip_serializing_if="String::is_empty")]
    pub api_version:String,
    #[serde(rename="fieldPath")]
    pub field_path:String,
}

#[derive(Deserialize,Serialize,Default,Clone,Debug)]
pub struct ResourceFieldSelector {
    #[serde(rename="containerName",default,skip_serializing_if="String::is_empty")]
    pub container_name:String,
    #[serde(rename="resource")]
    pub resource:String,
}

#[derive(Deserialize,Serialize,Default,Clone,Debug)]
pub struct ConfigMapKeySelector {
    #[serde(rename="name",default,skip_serializing_if="String::is_empty")]
    pub name:String,
    #[serde(rename="key")]
    pub key:String,
    #[serde(rename="optional",default,skip_serializing_if="Option::is_none")]
    pub optional:Option<bool>,
}

#[derive(Deserialize,Serialize,Default,Clone,Debug)]
pub struct SecretKeySelector {
    #[serde(rename="name",default,skip_serializing_if="String::is_empty")]
    pub name:String,
    #[serde(rename="key")]
    pub key:String,
    #[serde(rename="optional",default,skip_serializing_if="Option::is_none")]
    pub optional:Option<bool>,
}

#[derive(Deserialize,Serialize,Default,Clone,Debug)]
pub struct ResourceRequirements {
    #[serde(default,skip_serializing_if="HashMap::is_empty")]
    pub limits: HashMap<String,String>,
    #[serde(default,skip_serializing_if="HashMap::is_empty")]
    pub requests: HashMap<String,String>,
}


#[derive(Deserialize,Serialize,Default,Clone,Debug)]
pub struct VolumeMount {
    #[serde(rename="name")]
    pub name:String,
    #[serde(rename="readOnly",default,skip_serializing_if="Option::is_none")]
    pub read_only:Option<bool>,
    #[serde(rename="mountPath")]
    pub mount_path:String,
    #[serde(rename="subPath",default,skip_serializing_if="String::is_empty")]
    pub sub_path:String,
    #[serde(rename="mountPropagation",default,skip_serializing_if="String::is_empty")]
    pub mount_propagation:String,
    #[serde(rename="subPathExpr",default,skip_serializing_if="String::is_empty")]
    pub sub_path_expr:String,
}

#[derive(Deserialize,Serialize,Default,Clone,Debug)]
pub struct VolumeDevice {
    #[serde(rename="name")]
    pub name:String,
    #[serde(rename="devicePath")]
    pub device_path:String,
}

#[derive(Deserialize,Serialize,Default,Clone,Debug)]
pub struct Probe {
    #[serde(rename="exec",default,skip_serializing_if="Option::is_none")]
    pub exec:Option<ExecAction>,
    #[serde(rename="httpGet",default,skip_serializing_if="Option::is_none")]
    pub http_get:Option<HTTPGetAction>,
    #[serde(rename="tcpSocket",default,skip_serializing_if="Option::is_none")]
    pub tcp_socket:Option<TCPSocketAction>,
    #[serde(rename="initialDelaySeconds",default,skip_serializing_if="Option::is_none")]
    pub initial_delay_seconds:Option<i32>,
    #[serde(rename="timeoutSeconds",default,skip_serializing_if="Option::is_none")]
    pub timeout_seconds:Option<i32>,
    #[serde(rename="periodSeconds",default,skip_serializing_if="Option::is_none")]
    pub period_seconds:Option<i32>,
    #[serde(rename="successThreshold",default,skip_serializing_if="Option::is_none")]
    pub success_threshold:Option<i32>,
    #[serde(rename="failureThreshold",default,skip_serializing_if="Option::is_none")]
    pub failure_threshold:Option<i32>,
    #[serde(rename="terminationGracePeriodSeconds",default,skip_serializing_if="Option::is_none")]
    pub termination_grace_period_seconds:Option<i64>,
}

#[derive(Deserialize,Serialize,Default,Clone,Debug)]
pub struct ExecAction {
    #[serde(rename="command",default,skip_serializing_if="Vec::is_empty")]
    pub command:Vec<String>,
}

#[derive(Deserialize,Serialize,Default,Clone,Debug)]
pub struct HTTPGetAction {
    #[serde(rename="path",default,skip_serializing_if="String::is_empty")]
    pub path:String,
    #[serde(rename="port",default,skip_serializing_if="Option::is_none")]
    pub port:Option<i32>,
    #[serde(rename="host",default,skip_serializing_if="String::is_empty")]
    pub host:String,
    #[serde(rename="scheme",default,skip_serializing_if="String::is_empty")]
    pub scheme:String,
    #[serde(rename="httpHeaders",default,skip_serializing_if="Vec::is_empty")]
    pub http_headers:Vec<HTTPHeader>,
}

#[derive(Deserialize,Serialize,Default,Clone,Debug)]
pub struct HTTPHeader {
    pub name:String,
    pub value:String,
}

#[derive(Deserialize,Serialize,Default,Clone,Debug)]
pub struct TCPSocketAction {
    #[serde(rename="port")]
    pub port:Option<i32>,
    #[serde(rename="host",default,skip_serializing_if="String::is_empty")]
    pub host:String,
}

#[derive(Deserialize,Serialize,Default,Clone,Debug)]
pub struct SecurityContext {
    #[serde(rename="capabilities",default,skip_serializing_if="Option::is_none")]
    pub capabilities:Option<Capabilities>,
    #[serde(rename="privileged",default,skip_serializing_if="Option::is_none")]
    pub privileged:Option<bool>,
    #[serde(rename="runAsUser",default,skip_serializing_if="Option::is_none")]
    pub run_as_user:Option<i64>,
    #[serde(rename="runAsGroup",default,skip_serializing_if="Option::is_none")]
    pub run_as_group:Option<i64>,
    #[serde(rename="runAsNonRoot",default,skip_serializing_if="Option::is_none")]
    pub run_as_non_root:Option<bool>,
    #[serde(rename="readOnlyRootFilesystem",default,skip_serializing_if="Option::is_none")]
    pub read_only_root_filesystem:Option<bool>,
    #[serde(rename="allowPrivilegeEscalation",default,skip_serializing_if="Option::is_none")]
    pub allow_privilege_escalation:Option<bool>,
}

#[derive(Deserialize,Serialize,Default,Clone,Debug)]
pub struct Capabilities {
    #[serde(rename="add",default,skip_serializing_if="Vec::is_empty")]
    pub add:Vec<String>,
    #[serde(rename="drop",default,skip_serializing_if="Vec::is_empty")]
    pub drop:Vec<String>,
}

#[derive(Deserialize,Serialize,Default,Clone,Debug)]
pub struct EphemeralContainer {
    pub name:String,
    pub image:String,
    #[serde(default,skip_serializing_if="Vec::is_empty")]
    pub command:Vec<String>,
    #[serde(default,skip_serializing_if="Vec::is_empty")]
    pub args:Vec<String>,
    #[serde(rename="workingDir",default,skip_serializing_if="String::is_empty")]
    pub working_dir:String,
    #[serde(default,skip_serializing_if="Vec::is_empty")]
    pub ports:Vec<ContainerPort>,
    #[serde(rename="envFrom",default,skip_serializing_if="Vec::is_empty")]
    pub env_from:Vec<EnvFromSource>,
    #[serde(rename="env",default,skip_serializing_if="Vec::is_empty")]
    pub env:Vec<EnvVar>,
    #[serde(default,skip_serializing_if="Option::is_none")]
    pub resources:Option<ResourceRequirements>,
    #[serde(rename="volumeMounts",default,skip_serializing_if="Vec::is_empty")]
    pub volume_mounts:Vec<VolumeMount>,
    #[serde(rename="volumeDevices",default,skip_serializing_if="Vec::is_empty")]
    pub volume_devices:Vec<VolumeMount>,
    #[serde(rename="livenessProbe",default,skip_serializing_if="Option::is_none")]
    pub liveness_probe:Option<Probe>,
    #[serde(rename="readinessProbe",default,skip_serializing_if="Option::is_none")]
    pub readiness_probe:Option<Probe>,
    #[serde(rename="startupProbe",default,skip_serializing_if="Option::is_none")]
    pub startup_probe:Option<Probe>,
    #[serde(rename="terminationMessagePath",default,skip_serializing_if="String::is_empty")]
    pub termination_message_path:String,
    #[serde(rename="terminationMessagePolicy",default,skip_serializing_if="String::is_empty")]
    pub termination_message_policy:String,
    #[serde(rename="imagePullPolicy",default,skip_serializing_if="String::is_empty")]
    pub image_pull_policy:String,
    #[serde(rename="securityContext",default,skip_serializing_if="Option::is_none")]
    pub security_context:Option<SecurityContext>,
    #[serde(rename="stdin",default,skip_serializing_if="Option::is_none")]
    pub stdin:Option<bool>,
    #[serde(rename="stdinOnce",default,skip_serializing_if="Option::is_none")]
    pub stdin_once:Option<bool>,
    #[serde(rename="tty",default,skip_serializing_if="Option::is_none")]
    pub tty:Option<bool>,
    #[serde(rename="targetContainerName",default,skip_serializing_if="String::is_empty")]
    pub target_container_name:String,
}

#[derive(Deserialize,Serialize,Default,Clone,Debug)]
pub struct PodSecurityContext {
    #[serde(rename="runAsUser",default,skip_serializing_if="Option::is_none")]
    pub run_as_user:Option<i64>,
    #[serde(rename="runAsGroup",default,skip_serializing_if="Option::is_none")]
    pub run_as_group:Option<i64>,
    #[serde(rename="runAsNonRoot",default,skip_serializing_if="Option::is_none")]
    pub run_as_non_root:Option<bool>,
    #[serde(rename="supplementalGroups",default,skip_serializing_if="Vec::is_empty")]
    pub supplemental_groups:Vec<i64>,
}


#[cfg(test)]
mod test {
    use crate::types::pod::Pod;

    #[test]
    fn test () {
        let podstr = r#"{
    "apiVersion": "v1",
    "kind": "Pod",
    "metadata": {
        "creationTimestamp": "2022-11-29T03:19:27Z",
        "generateName": "mesh-ingress-",
        "labels": {
            "app": "mesh-ingress",
            "controller-revision-hash": "7c84dd4569",
            "mesh.resource": "ingress",
            "pod-template-generation": "2"
        },
        "name": "mesh-ingress-rw7k6",
        "namespace": "default",
        "ownerReferences": [
            {
                "apiVersion": "apps/v1",
                "blockOwnerDeletion": true,
                "controller": true,
                "kind": "DaemonSet",
                "name": "mesh-ingress",
                "uid": "f4861dae-24e1-4fd5-9db6-c58c24cb674a"
            }
        ],
        "resourceVersion": "357197",
        "uid": "162db599-6e49-4a10-97b6-7e12fa20fe41"
    },
    "spec": {
        "affinity": {
            "nodeAffinity": {
                "requiredDuringSchedulingIgnoredDuringExecution": {
                    "nodeSelectorTerms": [
                        {
                            "matchFields": [
                                {
                                    "key": "metadata.name",
                                    "operator": "In",
                                    "values": [
                                        "node1"
                                    ]
                                }
                            ]
                        }
                    ]
                }
            }
        },
        "containers": [
            {
                "image": "yh960124/daemon",
                "imagePullPolicy": "Always",
                "name": "daemon",
                "ports": [
                    {
                        "containerPort": 80,
                        "hostPort": 80,
                        "protocol": "TCP"
                    },
                    {
                        "containerPort": 25500,
                        "hostPort": 25500,
                        "protocol": "TCP"
                    }
                ],
                "resources": {},
                "terminationMessagePath": "/dev/termination-log",
                "terminationMessagePolicy": "File",
                "volumeMounts": [
                    {
                        "mountPath": "/opt/cni/bin",
                        "name": "cni-bin"
                    },
                    {
                        "mountPath": "/etc/cni/net.d",
                        "name": "cni-conf"
                    },
                    {
                        "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount",
                        "name": "kube-api-access-7fwlg",
                        "readOnly": true
                    }
                ]
            }
        ],
        "dnsPolicy": "ClusterFirst",
        "enableServiceLinks": true,
        "hostNetwork": true,
        "nodeName": "node1",
        "preemptionPolicy": "PreemptLowerPriority",
        "priority": 0,
        "restartPolicy": "Always",
        "schedulerName": "default-scheduler",
        "securityContext": {},
        "serviceAccount": "default",
        "serviceAccountName": "default",
        "terminationGracePeriodSeconds": 30,
        "tolerations": [
            {
                "effect": "NoExecute",
                "key": "node.kubernetes.io/not-ready",
                "operator": "Exists"
            },
            {
                "effect": "NoExecute",
                "key": "node.kubernetes.io/unreachable",
                "operator": "Exists"
            },
            {
                "effect": "NoSchedule",
                "key": "node.kubernetes.io/disk-pressure",
                "operator": "Exists"
            },
            {
                "effect": "NoSchedule",
                "key": "node.kubernetes.io/memory-pressure",
                "operator": "Exists"
            },
            {
                "effect": "NoSchedule",
                "key": "node.kubernetes.io/pid-pressure",
                "operator": "Exists"
            },
            {
                "effect": "NoSchedule",
                "key": "node.kubernetes.io/unschedulable",
                "operator": "Exists"
            },
            {
                "effect": "NoSchedule",
                "key": "node.kubernetes.io/network-unavailable",
                "operator": "Exists"
            }
        ],
        "volumes": [
            {
                "hostPath": {
                    "path": "/opt/cni/bin",
                    "type": "Directory"
                },
                "name": "cni-bin"
            },
            {
                "hostPath": {
                    "path": "/etc/cni/net.d",
                    "type": "Directory"
                },
                "name": "cni-conf"
            },
            {
                "name": "kube-api-access-7fwlg",
                "projected": {
                    "defaultMode": 420,
                    "sources": [
                        {
                            "serviceAccountToken": {
                                "expirationSeconds": 3607,
                                "path": "token"
                            }
                        },
                        {
                            "configMap": {
                                "items": [
                                    {
                                        "key": "ca.crt",
                                        "path": "ca.crt"
                                    }
                                ],
                                "name": "kube-root-ca.crt"
                            }
                        },
                        {
                            "downwardAPI": {
                                "items": [
                                    {
                                        "fieldRef": {
                                            "apiVersion": "v1",
                                            "fieldPath": "metadata.namespace"
                                        },
                                        "path": "namespace"
                                    }
                                ]
                            }
                        }
                    ]
                }
            }
        ]
    }
}"#;
        let v :Pod = serde_json::from_str(podstr).unwrap();
        println!("{:?}",v);
    }
}
